package com.yonyougov.devops.cruxcisupport.app;

import com.yonyougov.devops.cruxcisupport.app.dto.AppPageLikeDto;
import com.yonyougov.devops.cruxcisupport.app.dto.LinkAppDto;
import com.yonyougov.devops.cruxcisupport.app.vo.LinkAppVo;
import com.yonyougov.devops.cruxcisupport.app.vo.NoLinkAppByRoleIdDto;
import com.yonyougov.devops.cruxcisupport.app.vo.NoLinkAppVo;
import com.yonyougov.devops.cruxcisupport.appenv.AppEnvEntity;
import com.yonyougov.devops.cruxcisupport.appenv.AppEnvService;
import com.yonyougov.devops.cruxcisupport.appport.AppPortEntity;
import com.yonyougov.devops.cruxcisupport.appport.AppPortService;
import com.yonyougov.devops.cruxcisupport.role.RoleService;
import com.yonyougov.devops.cruxcisupport.roleapp.RoleAppEntity;
import com.yonyougov.devops.cruxcisupport.roleapp.RoleAppService;
import com.yonyougov.devops.cruxcisupport.version.VersionEntity;
import com.yonyougov.devops.cruxcisupport.version.VersionService;
import com.yonyougov.devops.fwc.core.dao.BaseDao;
import com.yonyougov.devops.fwc.core.entity.Pagination;
import com.yonyougov.devops.fwc.core.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import java.util.*;

/**
 * t_app服务实现
 */
@Service
public class AppServiceImpl extends BaseServiceImpl<AppEntity, BigInteger> implements AppService {
    private final AppDao appDao;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleAppService roleAppService;
    @Autowired
    private AppEnvService appEnvService;
    @Autowired
    private VersionService versionService;
    @Autowired
    private AppPortService appPortService;

    public AppServiceImpl(AppDao appDao) {
        this.appDao = appDao;
    }

    @Override
    public BaseDao<AppEntity, BigInteger> getDao() {
        return appDao;
    }

    //<!--用户自定义代码开始-->

    /**
     * 根据角色id和应用名称分页查询
     * @param appPageLikeDto [com.yonyougov.devops.cruxcisupport.app.dto.AppPageLikeDto] 参数
     * @return Pagination<AppEntity> [com.yonyougov.devops.cruxcisupport.app.AppEntity]
     */
    @Override
    public Pagination<AppEntity> findPageByRoleIds(AppPageLikeDto appPageLikeDto) throws Exception {
        if(null == appPageLikeDto.getRoleIds() || appPageLikeDto.getRoleIds().size() ==0){
            appPageLikeDto.setRoleIds(roleService.getCurrentUserRoleIds());
        }
        int totalCount = appDao.countByRoleIds(appPageLikeDto);
        List<AppEntity> appEntityList = appDao.findPageByRoleIds(appPageLikeDto);
        return new Pagination<AppEntity>(appPageLikeDto.getMax(),appPageLikeDto.getPageNum(),totalCount,appEntityList);
    }

    /**
     * 获取当前用户已关联的应用
     * @param linkAppDto com.yonyougov.devops.cruxcisupport.app.dto.LinkAppDto
     * @return List<LinkAppVo> com.yonyougov.devops.cruxcisupport.app.vo.LinkAppVo
     */
    @Override
    public List<LinkAppVo> findAppByRoleIds(LinkAppDto linkAppDto) throws Exception {
        if (null == linkAppDto.getRoleIds() || linkAppDto.getRoleIds().size() == 0) {
            linkAppDto.setRoleIds(roleService.getCurrentUserRoleIds());
        }
        return appDao.findAppByRoleIds(linkAppDto);
    }

    @Override
    public List<AppEntity> findById(List<BigInteger> ids) {
        return appDao.findById(ids);
    }

    /**
     * 根据角色查未关联的应用
     *
     * @param noLinkAppByRoleIdDto com.yonyougov.devops.cruxcisupport.app.vo.NoLinkAppByRoleIdDto
     * @return com.yonyougov.devops.cruxcisupport.app.vo.NoLinkAppVo
     */
    @Override
    public Pagination<NoLinkAppVo> findNoLinkAppPageByRoleId(NoLinkAppByRoleIdDto noLinkAppByRoleIdDto) {
        List<NoLinkAppVo> allAppNoLinkByRoleId = appDao.findNoLinkAppListByRoleId(noLinkAppByRoleIdDto);
        int totalCount = appDao.countNoLinkAppByRoleId(noLinkAppByRoleIdDto);

        return new Pagination<>(noLinkAppByRoleIdDto.getMax(), noLinkAppByRoleIdDto.getPageNum(), totalCount, allAppNoLinkByRoleId);
    }

    /**
     * 级联删除:删除app的同时，删除role_app,t_version,t_version_info,t_app_env
     * @param id appId
     */
    @Override
    public void deleteCascadeByPrimaryKey(BigInteger id) {
        this.deleteByPrimaryKey(id);
        //删除角色应用中间表
        RoleAppEntity roleAppEntity = new RoleAppEntity();
        roleAppEntity.setAppId(id);
        roleAppService.delete(roleAppEntity);
        //删除部署信息表
        AppEnvEntity appEnvEntity = new AppEnvEntity();
        appEnvEntity.setAppId(id);
        appEnvService.deleteAppEnvWithAppendages(appEnvEntity);
        //删除应用下的版本信息
        VersionEntity versionEntity = new VersionEntity();
        versionEntity.setAppId(id);
        versionService.deleteCascadeByPrimaryKey(versionEntity);
    }

    @Override
    public boolean isSettledHealthcheck(BigInteger appId){
        AppEntity appEntity = appDao.findByPrimaryKey(appId);
        return  null != appEntity.getHealthCheckPath() && "" != appEntity.getHealthCheckPath();
    }

    /**
     * 获取应用的的服务端口
     * 约定: 名称为http的即为服务端口
     * @param appId 应用id
     * @return 应用的服务端口
     */
    @Override
    public Integer getServiceInnerPort(BigInteger appId) throws Exception {
        AppPortEntity build = AppPortEntity.builder().appId(appId).build();
        build.setPageAble(false);
        List<AppPortEntity> datas = appPortService.findAllBy(build).getDatas();
        Map<String, List<AppPortEntity>> collect = datas.stream().collect(
                Collectors.groupingBy(AppPortEntity::getName)
        );
        if(!collect.containsKey("http") || (collect.containsKey("http") && 1 != collect.get("http").size())){
            throw new Exception("请为应用设置一个名称为http的服务端口");
        }
        return collect.get("http").get(0).getInternalPort();
    }
    //<!--用户自定义代码结束-->
}
